package cn.momoky.ccool.strategy;

import cn.momoky.ccool.exception.GlobalException;
import cn.momoky.ccool.util.JwtUtil;
import cn.momoky.ccool.utils.RedisCommand;
import cn.momoky.ccool.utils.ResultStatus;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

@Component
@AllArgsConstructor
public class AuthenticationStrategy {

    private final RedisCommand redisCommand;

    /* ----------- 鉴权相关方法 ----------- */



    /* ---------- token相关方法 ---------- */

    /**
     *功能描述 校验用户token，以及token续签
     * @author suosuo
     * @date 9/18/2021
      * @param token
     * @return java.lang.Boolean true：token生效，false：失效
     */
    public Boolean tokenAuthentication(String token){
        //1、token是否为空
        if (StringUtils.isEmpty(token)) return false;
        //2、token是否有效
        boolean tokenFlag = JwtUtil.checkToken(token);
         //token还是生效状态
        refreshCacheToken(token,token,true);
         //token为失效状态
        if(!tokenFlag) {
            Object cacheToken = getCacheToken(token);
            if (ObjectUtils.isEmpty(cacheToken)) return false;
            if(!JwtUtil.checkToken((String) cacheToken)) {
                refreshCacheToken(token,null,false);
            }else {
                refreshCacheToken(token, (String) cacheToken, true);
                return true;
            }
            return tokenAuthentication(token);
        }
        return true;
    }

    /**
     *功能描述 获取缓存中的token
     * @author suosuo
     * @date 9/18/2021
      * @param key
     * @return java.lang.Object
     */
    public Object getCacheToken(String key){
        Object o = redisCommand.get(key);
        return o;
    }

    /**
     *功能描述 刷新缓存中的token
     * @author suosuo
     * @date 9/18/2021
      * @param key
     * @param flag
     * @return java.lang.Object
     */
    public Object refreshCacheToken(String key,String value,boolean flag){
        if (flag) {
            redisCommand.set(key,value,4,TimeUnit.HOURS);
            return key;
        }
        //生成一个新的token
        String newToken = null;
        try {
            newToken = JwtUtil.getJwtToken(JwtUtil.getUserId(key),
                    JwtUtil.getUserName(key), JwtUtil.getIP(key),
                    JwtUtil.getMAC(key), JwtUtil.getRoleId(key));
        } catch (Exception e) {
            throw new GlobalException(ResultStatus.TOKEN_BUILD_FAIL);
        }
        redisCommand.set(key,newToken,4, TimeUnit.HOURS);
        return newToken;
    }
}
